package com.ygqh.baby.service.pay.app.alipay;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import com.ygqh.baby.ao.AppType;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;

public class AppAlipayNotifyTemplate {
	protected final Logger logger = Logger.getLogger(this.getClass());

	protected final static ExecutorService executorService = Executors.newFixedThreadPool(5);
	private Map<String, String> paramMap;

	public AppAlipayNotifyTemplate(Map<String, String[]> requestParams) {
		super();

		paramMap = AlipayAppUtils.getParameterMap(requestParams);

	}

	public String execute(PaySuccessCallBack successCallBack) {
		if (paramMap == null) {
			return "failure";
		}
		String result = "success";
		String passbackParams = paramMap.get("passback_params");
		String outTradeNo = paramMap.get("out_trade_no");
		System.out.println(JSON.toJSONString(paramMap));

		try {

			String publicKey = AlipayAppUtils.publickey;
			Boolean signVerified = AlipaySignature.rsaCheckV1(paramMap, publicKey, AlipayAppUtils.charSet, AlipayAppUtils.signType);
			if (signVerified) {
				// 验签成功后
				// 按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success，校验失败返回failure
				// 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
				// 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）
				// 3、校验通知中的seller_id（或者seller_email)
				// 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）

				/**
				 *  4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知，
				 *  正确的进行不同的业务处理，并且过滤重复的通知结果数据。在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
				 */
				String appId = paramMap.get("app_id");

				JSONObject params = JSON.parseObject(passbackParams);
				AppType appType = AppType.valueOf((String) params.get("appType"));
				Boolean checkAppId = AlipayAppUtils.checkAppId(appId);
				if (!checkAppId) {
					System.out.println(appId);
					result = "failure";
					logger.warn("支付宝支付回调验证appid失败；app_id=" + appId + ";paymentCode=" + outTradeNo + ";passbackParams=" + passbackParams);
				} else {

					String tradeStatus = paramMap.get("trade_status");
					String tradeNo = paramMap.get("trade_no");
					String paidPrice = paramMap.get("total_amount");
					String paidTime = paramMap.get("notify_time");

					if (StringUtils.isNotBlank(tradeStatus) && ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus))) {
						executorService.execute(new Runnable() {
							public void run() {
								try {

									Date time = DateConvertUtils.parse(paidTime, DateConvertUtils.DATE_TIME_FORMAT);

									successCallBack.onSuccess(tradeNo, outTradeNo, appType, params, tradeStatus, new BigDecimal(paidPrice), time);
								} catch (Exception e) {
									logger.error("支付宝支付回调 执行业务逻辑失败；app_id=" + appId + ";paymentCode=" + outTradeNo + ";passbackParams=" + passbackParams + ";"
											+ ExceptionUtil.getExceptionMsg(e));
									e.printStackTrace();
								}
							}
						});
					} else {
						logger.warn("alipay支付回调：支付状态非支付成功 ，tradeStatus = " + tradeStatus + "，paymentCode=" + outTradeNo + "的未支付订单。tradeNo=" + tradeNo
								+ ";appType=" + appType);
					}
				}
			} else {
				// 验签失败则记录异常日志，并在response中返回failure.
				result = "failure";
				logger.warn("支付宝支付回调验签失败；paymentCode=" + outTradeNo + ";passbackParams=" + passbackParams);
			}
		} catch (Exception e) {
			e.printStackTrace();
			result = "failure";
			logger.error("支付宝支付回调验签失败；paymentCode=" + outTradeNo + ";passbackParams=" + passbackParams);
		}

		return result;

	}

}
